package com.lonely.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.enums.CommonStatus;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.product.domain.entity.SysCuttingBed;
import com.lonely.product.domain.entity.SysCuttingBedSize;
import com.lonely.product.mapper.SysCuttingBedSizeMapper;
import com.lonely.product.service.ICuttingBedService;
import com.lonely.product.service.ICuttingBedSizeService;
import com.lonely.order.domain.entity.SysOrderPart;
import com.lonely.order.domain.vo.order.OrderQuantityInfo;
import com.lonely.order.service.IOrderPartService;
import com.lonely.order.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/25 10:29
 * @description: 裁床尺码服务实现类
 */
@Service
public class CuttingBedSizeServiceImpl extends ServiceImpl<SysCuttingBedSizeMapper, SysCuttingBedSize> implements ICuttingBedSizeService {

    @Autowired
    private IOrderPartService orderPartService;

    @Autowired
    private ICuttingBedService cuttingBedService;

    @Autowired
    private IOrderService orderService;

    /**
     * 修改裁床尺码
     *
     * @param id
     * @param sizes
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSize(Long id, OrderQuantityInfo sizes) {

        SysCuttingBed sysCuttingBed = this.cuttingBedService.getById(id);

        // 根据不同部件来更新尺码数量
        Map<Long, String> partIdNameMap = this.orderPartService.list(new LambdaQueryWrapper<SysOrderPart>()
                .eq(SysOrderPart::getProduceOrderId, sysCuttingBed.getProduceOrderId())
        ).stream().collect(Collectors.toMap(BaseEntity::getId, SysOrderPart::getPartLibrary));


        boolean isSuit = this.orderService.isSuit(sysCuttingBed.getProduceOrderId());

        partIdNameMap.forEach((partId, partName) -> {

            List<SysCuttingBedSize> cuttingBedSizes = super.list(new LambdaQueryWrapper<SysCuttingBedSize>()
                    .eq(SysCuttingBedSize::getCuttingBedId, id)
                    .eq(SysCuttingBedSize::getOrderPartId, partId)
                    .eq(SysCuttingBedSize::getStatus, CommonStatus.ENABLE.code)
            );
            List<String> sizeNames = cuttingBedSizes.stream().map(SysCuttingBedSize::getSizeName).distinct().collect(Collectors.toList());

            // 接口中当前部件的尺码数量配置
            Map<String, Object> newSizes;
            if (isSuit) {
                newSizes = sizes.getData().stream().filter(x -> Objects.equals(MapUtil.getStr(x, "type"), String.format("%s-裁床数", partName))).findFirst().orElse(new HashMap<>());
            } else {
                // 非套装
                newSizes = sizes.getData().stream().filter(x -> Objects.equals(MapUtil.getStr(x, "type"), "裁床数")).findFirst().orElse(new HashMap<>());
            }

            List<String> newSizeNames = newSizes.keySet().stream().filter(x -> !Objects.equals(x, "type") && !Objects.equals(x, "total"))
                    .filter(x -> newSizes.get(x) != null)
                    .distinct().collect(Collectors.toList());

            // 获取新增的尺码
            Collection<String> needAddSizeNames = CollUtil.subtract(newSizeNames, sizeNames);

            // 获取待删除的尺码
            Collection<String> needDeleteSizeNames = CollUtil.subtract(sizeNames, newSizeNames);

            // 获取待更新的尺码
            Collection<String> needUpdateSizeNames = CollUtil.intersection(newSizeNames, sizeNames);

            if (CollUtil.isNotEmpty(needAddSizeNames)) {
                List<SysCuttingBedSize> needAddSizeEntity = newSizes.entrySet().stream().filter(x -> needAddSizeNames.contains(x.getKey())).map(x -> {
                    SysCuttingBedSize sysCuttingBedSize = new SysCuttingBedSize();
                    sysCuttingBedSize.setCuttingBedId(id);
                    sysCuttingBedSize.setOrderPartId(partId);
                    sysCuttingBedSize.setSizeName(x.getKey());
                    sysCuttingBedSize.setQuantity(Convert.toInt(x.getValue()));
                    sysCuttingBedSize.setCreateBy(SecurityUtils.getUserId());
                    sysCuttingBedSize.setUpdateBy(SecurityUtils.getUserId());
                    return sysCuttingBedSize;
                }).collect(Collectors.toList());
                super.saveBatch(needAddSizeEntity);
            }

            if (CollUtil.isNotEmpty(needDeleteSizeNames)) {
                super.remove(new LambdaQueryWrapper<SysCuttingBedSize>()
                        .in(SysCuttingBedSize::getSizeName, needDeleteSizeNames)
                );
            }

            if (CollUtil.isNotEmpty(needUpdateSizeNames)) {
                List<SysCuttingBedSize> needUpdateSizeEntity = cuttingBedSizes.stream().filter(x -> needUpdateSizeNames.contains(x.getSizeName())).peek(x -> {
                    x.setQuantity(Convert.toInt(newSizes.get(x.getSizeName())));
                    x.setUpdateBy(SecurityUtils.getUserId());
                }).collect(Collectors.toList());
                super.updateBatchById(needUpdateSizeEntity);
            }


        });


    }
}
